﻿/*
 * KLF Headless Browser
 * Written by Kris Oye <kristianoye@gmail.com>
 * Copyright (C) 2011-2012.  All rights reserved.
 */
namespace KLF.Lib.Browser.DOM.HTML
{
    #region Using Statements

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    #endregion

    public class HTMLTableRowElement : HTMLBlockBaseElement
    {
        #region Constructors

        internal HTMLTableRowElement(Document owner)
            : base(owner, HTMLConstants.HTML_TAG_TABLEROW)
        {
        }

        #endregion

        #region DOM Level 2 HTML Compliance

        /// <summary>
        /// Background color for rows. See the bgcolor attribute definition 
        /// in HTML 4.01. This attribute is deprecated in HTML 4.01.
        /// </summary>
        [Obsolete]
        public string bgColor
        {
            get
            {
                return getAttribute(HTMLConstants.HTML_ATT_BGCOLOR);
            }
            set
            {
                setAttribute(HTMLConstants.HTML_ATT_BGCOLOR, value);
            }
        }

        /// <summary>
        /// The collection of cells in this row.
        /// </summary>
        public HTMLCollection cells
        {
            get
            {
                Type cellType = typeof(HTMLTableCellElement);
                return new HTMLCollection(Owner, Elements
                    .Where(e => e.GetType() == cellType)
                    .Cast<Node>());
            }
        }

        /// <summary>
        /// Alignment character for cells in a column. 
        /// 
        /// See the char attribute definition in HTML 4.01.
        /// </summary>
        public string ch
        {
            get
            {
                return getAttribute(HTMLConstants.HTML_ATT_CHAR);
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                    removeAttribute(HTMLConstants.HTML_ATT_CHAR);
                else
                    setAttribute(HTMLConstants.HTML_ATT_CHAR, value);
            }
        }

        /// <summary>
        /// Offset of alignment character. 
        /// 
        /// See the charoff attribute definition in HTML 4.01.
        /// </summary>
        public string chOff
        {
            get
            {
                return getAttribute(HTMLConstants.HTML_ATT_CHAROFF);
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                    removeAttribute(HTMLConstants.HTML_ATT_CHAROFF);
                else
                    setAttribute(HTMLConstants.HTML_ATT_CHAROFF, value);
            }
        }

        /// <summary>
        /// Delete a cell from the current row.
        /// </summary>
        /// <param name="index">The index of the cell to delete, starting from 0. 
        /// 
        /// If the index is -1 the last cell in the row is deleted.</param>
        public void deleteCell(int index)
        {
            HTMLCollection c = cells;

            if (index == -1)
                index = c.length - 1;

            if (index < 0 || index >= cells.length)
                throw new DOMException(DOMException.INDEX_SIZE_ERR);
            else
                cells.item(index).Parent.removeChild(cells.item(index));
        }

        /// <summary>
        /// Insert an empty TD cell into this row. If index is -1 or equal to 
        /// the number of cells, the new cell is appended. 
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public HTMLElement insertCell(int index)
        {
            HTMLTableCellElement cell = (HTMLTableCellElement)Owner.createElement(HTMLConstants.HTML_TAG_TABLECELL);
            HTMLCollection c = cells;

            if (index < -1 || index > cells.length)
                throw new DOMException(DOMException.INDEX_SIZE_ERR);
            else if (index == -1 || index == cells.length)
                appendChild(cell);
            else
                c.item(index).Parent.insertBefore(cell, c.item(index));

            return cell;
        }

        /// <summary>
        /// This is in logical order and not in document order. 
        /// 
        /// The rowIndex does take into account sections (THEAD, TFOOT, or 
        /// TBODY) within the table, placing THEAD rows first in the index,
        /// followed by TBODY rows, followed by TFOOT rows.
        /// </summary>
        public int rowIndex
        {
            get
            {
                HTMLTableElement table = tableElement;

                if (table != null)
                {
                    HTMLCollection r = tableElement.logicalRows;
                    return r.Nodes.IndexOf(this);
                }
                return -1;
            }
        }

        /// <summary>
        /// The index of this row, relative to the current section (THEAD, 
        /// TFOOT, or TBODY), starting from 0.
        /// </summary>
        public int sectionRowIndex
        {
            get
            {
                HTMLElement p = this;

                do
                {
                    p = p.Parent as HTMLElement;
                }
                while (p != null && !(p is HTMLTableSectionElement));

                if (p != null)
                {
                    HTMLTableSectionElement s = p as HTMLTableSectionElement;
                    HTMLCollection items = s.rows;

                    return s.rows.Nodes.IndexOf(this);
                }
                return -1;
            }
        }

        /// <summary>
        /// Vertical alignment of cell data in column. 
        /// 
        /// See the valign attribute definition in HTML 4.01.
        /// </summary>
        public string vAlign
        {
            get
            {
                return getAttribute(HTMLConstants.HTML_ATT_VALIGN);
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                    removeAttribute(HTMLConstants.HTML_ATT_VALIGN);
                else
                    setAttribute(HTMLConstants.HTML_ATT_VALIGN, value);
            }
        }

        #endregion

        #region Custom Attributes

        /// <summary>
        /// Returns the containing table element or null if unattached.
        /// </summary>
        public HTMLTableElement tableElement
        {
            get
            {
                HTMLElement p = this;
                do
                {
                    p = p.Parent as HTMLElement;
                    if (p is HTMLTableElement)
                        return (HTMLTableElement)p;
                }
                while (p != null);
                return null;
            }
        }

        /// <summary>
        /// Returns the containing table section element or null if unattached.
        /// </summary>
        public HTMLTableSectionElement tableSection
        {
            get
            {
                HTMLElement p = this;
                do
                {
                    p = p.Parent as HTMLElement;

                    if (p is HTMLTableSectionElement)
                        return (HTMLTableSectionElement)p;
                }
                while (p != null);
                return null;
            }
        }

        #endregion
    }
}
